package com.lzqinga.service;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lzqinga.service.storage.VideoCompositionService;
import com.lzqinga.service.storage.VideoSegmentService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author lzqinga@126.com
 * @Date 2025/10/10  20:12
 */
@Service
@Slf4j
public class VideoGeneratorService {

    @Autowired
    private VideoSegmentService videoSegmentService;

    @Autowired
    private VideoCompositionService videoCompositionService;

    @Autowired
    private XunFeiService xunFeiService;

    @Autowired
    private XxunFeiAIService xxunFeiAIService;

    // 配置常量
    private static final String TEXT_MODEL = "ernie-4.5-turbo-128k";
    private static final String TEXT_API_URL = "https://qianfan.baidubce.com/v2/chat/completions";
    private static final String IMAGE_API_URL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/text2image/sd_xl";
    private static final String TTS_API_URL = "https://aip.baidubce.com/rpc/2.0/tts/v1/create";
    private static final String VIDEO_API_URL = "https://api.example.com/video/generate"; // 替换为实际视频API

    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder()
            .readTimeout(300, TimeUnit.SECONDS)
            .build();

    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 顶层 API 响应结构
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class QianfanApiResponse {
        public String id;
        public String object;
        public long created;
        public String model;
        public List<Choice> choices;
        public Usage usage;
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Choice {
        public int index;
        public Message message;
        public String finish_reason;
        public int flag;
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Message {
        public String role;
        public String content;
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Usage {
        public int prompt_tokens;
        public int completion_tokens;
        public int total_tokens;
    }

    // 内容中的 JSON 结构
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Segment {
        public String content; // 字幕文本
        public String imagePrompt;
        public String emotion;
        public int segmentIndex;

        // 生成的文件路径
        public String imagePath;      // 图片文件路径
        public String audioPath;      // 音频文件路径

        public String videoPath;    //视频路径
        public Double duration;       // 片段时长
        public String transition;     // 转场效果
        public Double transitionDuration; // 转场时长

        // 计算属性
        public Double startTime;      // 在最终视频中的开始时间
        public Double endTime;        // 在最终视频中的结束时间
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class SegmentResponse {
        public List<Segment> segments;
        public String overallTheme;
        public ErrorDetail error;

        // 检查响应是否成功
        public boolean isSuccess() {
            return error == null;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ErrorDetail {
        public String code;
        public String message;
        public String type;
    }

    /**
     * 主流程：从文本生成完整视频
     * @param inputText 输入文本
     * @param textToken 文本API token
     * @param appId 应用ID
     * @param imageToken 图片API token
     * @param ttsToken 语音API token
     * @param videoToken 视频API token
     * @param outputDir 输出目录
     * @return 最终视频路径
     */
    public String generateVideoFromText(String inputText,
                                               String textToken, String appId,
                                               String imageToken,
                                               String ttsToken,
                                               String videoToken,
                                               String outputDir) throws Exception {

        // 1. 调用大模型分析文本
        String jsonResponse = analyzeText(inputText, textToken, appId);
        System.out.println("返回的json数据：jsonResponse = " + jsonResponse);

        // 2. 解析JSON响应
        SegmentResponse segmentResponse = parseSegmentResponse(jsonResponse);

        System.out.println("json转对象：segmentResponse = " + segmentResponse.toString());

        // 3. 检查响应是否成功
        if (!segmentResponse.isSuccess()) {
            throw new IOException("文本分析失败: " + segmentResponse.error.message);
        }

        // 3. 创建输出目录
        File outputDirFile = new File(outputDir);
        if (!outputDirFile.exists()) {
            outputDirFile.mkdirs();
        }

        List<String> paths = new ArrayList<>();
        // 4. 处理每个片段
        for (Segment segment : segmentResponse.segments) {
            System.out.println("处理片段 #" + segment.segmentIndex + ": " + segment.content);

            // 生成图片
            String imagePath = generateImageForSegment(segment, imageToken, outputDir);
            segment.imagePath = imagePath;

            // 生成语音
            String audioPath = generateAudioForSegment(segment, ttsToken, outputDir);
            segment.audioPath = audioPath;

            waitForFileGeneration(imagePath, audioPath);

            // 生成视频片段
            String videoPath = videoSegmentService.createVideoSegment(segment);
            segment.videoPath = videoPath;
            paths.add(videoPath);
        }

        // 5. 组合所有片段为完整视频
        String finalVideoPath = videoCompositionService.composeVideoSegments(paths, segmentResponse.segments, outputDir);

        return finalVideoPath;
    }

    /**
     * 等待文件生成完成
     */
    private void waitForFileGeneration(String imagePath, String audioPath) {
        int maxRetries = 30; // 最大重试次数
        int retryInterval = 2000; // 重试间隔1秒

        for (int i = 0; i < maxRetries; i++) {
            File imageFile = new File(imagePath);
            File audioFile = new File(audioPath);

            if (imageFile.exists() && imageFile.length() > 0 &&
                    audioFile.exists() && audioFile.length() > 0) {
                log.debug("文件生成完成: {} ({} bytes), {} ({} bytes)",
                        imagePath, imageFile.length(), audioPath, audioFile.length());
                return;
            }

            try {
                Thread.sleep(retryInterval);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("等待文件生成被中断", e);
            }
        }

        throw new RuntimeException("文件生成超时: " + imagePath + ", " + audioPath);
    }

    /**
     * 分析文本并返回片段信息
     */
    private static String analyzeText(String inputText, String token, String appId) throws IOException {
        // 构建消息内容
        String content = "请将以下文本分解为3-5个适合制作视频的片段。每个片段需要包含：\n" +
                "1. 文本内容（简洁明了，适合配音）\n" +
                "2. 图片描述（详细的视觉描述，风格必须统一，必须是实景，写实，用于AI生成图片）\n" +
                "3. 情感基调（如：欢快、严肃、温馨等）\n\n" +
                "请严格按照JSON格式返回，结构如下：\n" +
                "{\n" +
                "  \"segments\": [\n" +
                "    {\n" +
                "      \"content\": \"片段文本内容\",\n" +
                "      \"imagePrompt\": \"详细的图片描述（包括场地实景、风格、环境描述等等）\",\n" +
                "      \"emotion\": \"情感基调\",\n" +
                "      \"segmentIndex\": 1\n" +
                "    }\n" +
                "  ],\n" +
                "  \"overallTheme\": \"整体主题\"\n" +
                "}\n\n" +
                "待分析的文本：\n" + inputText;

        // 构建请求体
        Map<String, Object> requestBody = new LinkedHashMap<>();
        requestBody.put("model", TEXT_MODEL);

        // 构建消息列表
        List<Map<String, String>> messages = new ArrayList<>();
        Map<String, String> userMessage = new HashMap<>();
        userMessage.put("role", "user");
        userMessage.put("content", content);
        messages.add(userMessage);
        requestBody.put("messages", messages);

        // 构建web_search对象
        Map<String, Boolean> webSearch = new HashMap<>();
        webSearch.put("enable", false);
        webSearch.put("enable_citation", false);
        webSearch.put("enable_trace", false);
        requestBody.put("web_search", webSearch);

        // 空插件选项
        requestBody.put("plugin_options", Collections.emptyMap());

        // 转换为JSON字符串
        String jsonBody = objectMapper.writeValueAsString(requestBody);

        // 创建请求
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, jsonBody);
        Request request = new Request.Builder()
                .url(TEXT_API_URL)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer " + token)
                .addHeader("appid", "")
                .build();

        // 执行请求并返回结果
        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            return response.body().string();
        }
    }

    /**
     * 解析JSON响应
     */
    private static SegmentResponse parseSegmentResponse(String jsonResponse) throws IOException {
        // 先检查响应是否包含错误
        if (jsonResponse.contains("\"error\"")) {
            // 尝试解析为错误响应
//            SegmentResponse response = objectMapper.readValue(jsonResponse, SegmentResponse.class);
//            if (response.error != null) {
//                throw new IOException("API错误: " + response.error.code + " - " + response.error.message);
//            }
            throw new IOException("API错误: " + jsonResponse);
        }

        try {
            // 1. 解析顶层 API 响应
            QianfanApiResponse apiResponse = objectMapper.readValue(jsonResponse, QianfanApiResponse.class);

            // 2. 检查是否有错误
            if (apiResponse.choices == null || apiResponse.choices.isEmpty()) {
                throw new IOException("API响应缺少choices字段");
            }

            // 3. 获取第一个 choice 的内容
            String content = apiResponse.choices.get(0).message.content;

            // 4. 提取内容中的 JSON
            String jsonContent = extractJsonFromContent(content);

            // 5. 解析为 SegmentResponse 对象
            return objectMapper.readValue(jsonContent, SegmentResponse.class);
        } catch (JsonProcessingException e) {
            throw new IOException("解析API响应失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从内容字符串中提取 JSON
     */
    private static String extractJsonFromContent(String content) {
        // 查找 JSON 代码块的开始和结束位置
        int startIndex = content.indexOf("```json");
        if (startIndex == -1) {
            startIndex = content.indexOf("{");
        } else {
            startIndex += "```json".length();
        }

        int endIndex = content.lastIndexOf("```");
        if (endIndex == -1) {
            endIndex = content.lastIndexOf("}");
        } else {
            endIndex = content.lastIndexOf("```");
        }

        if (startIndex == -1 || endIndex == -1 || endIndex <= startIndex) {
            // 如果没有找到代码块标记，返回整个内容
            return content;
        }

        // 提取 JSON 部分
        return content.substring(startIndex, endIndex).trim();
    }

    /**
     * 为片段生成图片
     */
    private static String generateImageForSegment(Segment segment, String token, String outputDir) throws IOException {
        System.out.println("生成图片： ==== ");
        // 使用之前封装的ImagesService
        String imageResponse = ImagesService.generateImage(
                segment.imagePrompt,
                "", // 负面提示词
                1,
                token
        );
        System.out.println("生成成功，进行下载： ==== ");
        String imagePath = outputDir + "segment_" + segment.segmentIndex + ".jpg";
        ImagesService.saveImage(imageResponse, imagePath);
        System.out.println("下载成功，图片路径： ==== " + imagePath);
        return imagePath;
    }

    /**
     * 为片段生成语音
     */
    private String generateAudioForSegment(Segment segment, String token, String outputDir) throws Exception {
//        System.out.println("生成语音： = ");
//        String fileName = outputDir + "segment_" + segment.segmentIndex + ".mp3";
//        xunFeiService.tts(segment.content, fileName);
//        System.out.println("生成语音路径： = " + fileName);
//        return fileName;

        System.out.println("生成语音： = ");
        String fileName = "segment_" + segment.segmentIndex;
        XxunFeiAIService.TtsResult result = xxunFeiAIService.textToSpeech(segment.content, outputDir, fileName, null);
        System.out.println("生成语音路径： = " + fileName);
        return fileName;

    }

    /**
     * 根据情感选择发音人
     */
    private static int chooseVoiceByEmotion(String emotion) {
        // 根据情感基调选择合适的发音人
        if (emotion.contains("欢快") || emotion.contains("开心")) {
            return 5118; // 欢快女声
        } else if (emotion.contains("严肃") || emotion.contains("庄重")) {
            return 5003; // 严肃男声
        } else if (emotion.contains("温馨") || emotion.contains("温柔")) {
            return 5117; // 温柔女声
        } else {
            return 0; // 默认发音人
        }
    }

    /**
     * 生成视频片段
     */
    private static String generateVideoSegment(Segment segment, String token, String outputDir) throws IOException {
        // 构建视频生成请求
        Map<String, Object> videoRequest = new HashMap<>();
        videoRequest.put("image_path", segment.imagePath);
        videoRequest.put("audio_path", segment.audioPath);
        videoRequest.put("duration", calculateDuration(segment.audioPath)); // 根据音频长度计算视频时长
        videoRequest.put("token", token);

        String jsonBody = objectMapper.writeValueAsString(videoRequest);

        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, jsonBody);
        Request request = new Request.Builder()
                .url(VIDEO_API_URL)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();

        // 执行请求
        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            // 解析响应获取视频URL
            String videoUrl = parseVideoUrlFromResponse(response.body().string());

            // 下载视频片段
            String videoPath = downloadVideo(videoUrl, outputDir, "segment_" + segment.segmentIndex + ".mp4");

            return videoPath;
        }
    }

    /**
     * 组合所有片段为完整视频
     */
    private static String combineSegments(SegmentResponse response, String outputDir) throws IOException {
        // 这里简化处理，实际需要调用视频拼接API
        // 或者使用FFmpeg等工具本地拼接

        List<String> videoPaths = new ArrayList<>();
        for (Segment segment : response.segments) {
            videoPaths.add(segment.videoPath);
        }

        // 假设调用视频拼接API
        Map<String, Object> combineRequest = new HashMap<>();
        combineRequest.put("video_paths", videoPaths);
        combineRequest.put("overall_theme", response.overallTheme);

        String jsonBody = objectMapper.writeValueAsString(combineRequest);

        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, jsonBody);
        Request request = new Request.Builder()
                .url(VIDEO_API_URL + "/combine")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();

        // 执行请求
        try (Response response1 = HTTP_CLIENT.newCall(request).execute()) {
            // 解析响应获取最终视频URL
            String finalVideoUrl = parseVideoUrlFromResponse(response1.body().string());

            // 下载最终视频
            String finalVideoPath = downloadVideo(finalVideoUrl, outputDir, "final_video.mp4");

            return finalVideoPath;
        }
    }

    // 辅助方法（需要根据实际API响应实现）
    private static String parseImageUrlFromResponse(String response) {
        // 解析图片URL
        return "https://example.com/image.jpg";
    }

    private static String parseAudioUrlFromResponse(String response) {
        // 解析音频URL
        return "https://example.com/audio.mp3";
    }

    private static String parseVideoUrlFromResponse(String response) {
        // 解析视频URL
        return "https://example.com/video.mp4";
    }

    private static String downloadImage(String url, String outputDir, String fileName) {
        // 下载图片并返回本地路径
        return outputDir + "/" + fileName;
    }

    private static String downloadAudio(String url, String outputDir, String fileName) {
        // 下载音频并返回本地路径
        return outputDir + "/" + fileName;
    }

    private static String downloadVideo(String url, String outputDir, String fileName) {
        // 下载视频并返回本地路径
        return outputDir + "/" + fileName;
    }

    private static int calculateDuration(String audioPath) {
        // 根据音频文件计算时长（秒）
        return 10; // 示例值
    }

    // 测试主方法
    public static void main(String[] args) {
        VideoGeneratorService videoGeneratorService =  new VideoGeneratorService();
        try {
            String textToken = "bce-v3/ALTAK-7E9eb6lRRPwixxdqYc76p/786cadc5603df42c8459dc24aea8df3d175b6548";
            String appId = "app-Rkqmn9vp";
            String imageToken = "bce-v3/ALTAK-7E9eb6lRRPwixxdqYc76p/786cadc5603df42c8459dc24aea8df3d175b6548";
            String ttsToken = "bce-v3/ALTAK-7E9eb6lRRPwixxdqYc76p/786cadc5603df42c8459dc24aea8df3d175b6548";
            String videoToken = "bce-v3/ALTAK-7E9eb6lRRPwixxdqYc76p/786cadc5603df42c8459dc24aea8df3d175b6548";
            String outputDir = "output/videos";

            String finalVideo = videoGeneratorService.generateVideoFromText(
                    "故宫的雪",
                    textToken, appId,
                    imageToken,
                    ttsToken,
                    videoToken,
                    outputDir
            );

            System.out.println("视频生成完成: " + finalVideo);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
